/*
 * 文件名：power_management.cpp
 * 功能描述：电源管理和低功耗模式控制
 */
#include <Arduino.h>
#include <esp_sleep.h>
#include <esp_bt.h>
#include <esp_bt_main.h>
#include <esp_pm.h>
#include <bsp_ble.h>
#include <config.h>
#include "Display_ST7789.h" // 添加ST7789显示驱动头文件

const uint32_t MAX_FREQ_MHZ = 240; // 最大CPU频率
const uint32_t MIN_FREQ_MHZ = 80;  // 提高最小CPU频率以确保蓝牙稳定性
// bool deviceConnected = false;
int64_t last_ble_activity = 0;
const int64_t BLE_IDLE_TIMEOUT = 20000000; // 增加到10秒无活动后进入低功耗模式 (单位：微秒)
int64_t last_serial_activity = 0;
const int64_t SERIAL_IDLE_TIMEOUT = 5000000;   // 串口空闲超时5秒（与BLE相同）
int64_t last_encoder_activity = 0;             // 新增：编码器最后活动时间
const int64_t ENCODER_IDLE_TIMEOUT = 10000000; // 新增：编码器空闲超时10秒
extern bool deviceConnected_g;
// 低功耗状态标志
bool is_power_save_mode = false;
bool is_lcd_power_save_mode = false;
bool motor_enable = false;
TaskHandle_t powerManagementTaskHandle = NULL;
SemaphoreHandle_t powerMutex = NULL;

// 获取当前时间（微秒）
int64_t get_current_time()
{
    return esp_timer_get_time();
}

void LCD_exit_power_save_mode()
{
    if (!is_lcd_power_save_mode)
    {
        return; // 如果不在低功耗模式，直接返回
    }
    if (print_key)
    {
        Serial.println("已退出低功耗模式");
    }

    // 恢复LCD显示
    digitalWrite(EXAMPLE_PIN_NUM_LCD_CS, LOW); // 启用SPI通信
    LCD_WriteCommand(0x11);                    // 退出睡眠模式
    delay(120);                                // 等待显示稳定
    LCD_WriteCommand(0x29);                    // 开启显示
    Set_Backlight(255);                        // 恢复背光

    is_lcd_power_save_mode = false;
}

void exit_power_save_mode()
{
    if (!is_power_save_mode)
    {
        return; // 如果不在低功耗模式，直接返回
    }

    // 恢复CPU频率
    setCpuFrequencyMhz(MAX_FREQ_MHZ);
    if (print_key)
    {
        Serial.printf("CPU频率已恢复至: %d MHz\n", MAX_FREQ_MHZ);
        Serial.println("已退出低功耗模式");
    }

    is_power_save_mode = false;
}

// 更新蓝牙活动时间
void update_ble_activity()
{
    last_ble_activity = get_current_time();
    // 如果当前在低功耗模式，收到蓝牙消息时退出
    if (is_power_save_mode)
    {
        exit_power_save_mode();
    }
}

// 检查蓝牙是否空闲
bool is_ble_idle()
{
    if (last_ble_activity == 0)
    {
        last_ble_activity = get_current_time(); // 初始化时间戳
        return false;
    }
    return (get_current_time() - last_ble_activity) > BLE_IDLE_TIMEOUT;
}

bool is_serial_idle()
{
    if (last_serial_activity == 0)
    {
        last_serial_activity = get_current_time(); // 初始化时间戳
        return false;
    }
    return (get_current_time() - last_serial_activity) > SERIAL_IDLE_TIMEOUT;
}

void update_serial_activity()
{
    last_serial_activity = get_current_time();
    // if (is_power_save_mode) {
    //     exit_power_save_mode();
    // }
}

// 新增：更新编码器活动时间
void update_encoder_activity()
{
    last_encoder_activity = get_current_time();
    if (is_lcd_power_save_mode)
    {
        LCD_exit_power_save_mode();
    }
    if (is_power_save_mode)
    {
        exit_power_save_mode();
    }
}

// 新增：检查编码器是否空闲
bool is_encoder_idle()
{
    if (last_encoder_activity == 0)
    {
        last_encoder_activity = get_current_time(); // 初始化时间戳
        return false;
    }
    bool en = ((get_current_time() - last_encoder_activity) > ENCODER_IDLE_TIMEOUT);
    return en;
}

// 进入低功耗模式
void LCD_enter_power_save_mode()
{

    if (is_lcd_power_save_mode)
    {
        return; // 如果已经在低功耗模式，直接返回
    }

    if (print_key)
    {
        Serial.println("正在进入LCD低功耗模式...");
    }
    // 关闭LCD显示
    LCD_WriteCommand(0x10);                     // 进入睡眠模式
    Set_Backlight(0);                           // 关闭背光
    digitalWrite(EXAMPLE_PIN_NUM_LCD_CS, HIGH); // 禁用SPI通信
    vTaskDelay(100 / portTICK_PERIOD_MS);

    is_lcd_power_save_mode = true;
}

void enter_power_save_mode()
{
    if (is_power_save_mode)
    {
        return; // 如果已经在低功耗模式，直接返回
    }

    if (print_key)
    {
        Serial.println("进入低功耗模式...");
    }

    // 降低CPU频率
    setCpuFrequencyMhz(MIN_FREQ_MHZ);
    uint32_t actual_freq = getCpuFrequencyMhz();
    if (print_key)
    {
        Serial.printf("设定频率: %d MHz, 实际频率: %d MHz\n", MIN_FREQ_MHZ, actual_freq);
    }

    // 确保BLE控制器保持活动
    // esp_bt_controller_enable(ESP_BT_MODE_BLE);

    is_power_save_mode = true;
}

void power_management_task(void *pvParameters)
{
    while (true)
    {
        Serial.println("检测到空闲");
        if (is_encoder_idle())
        {
            // Serial.println("检测到空闲");  // 添加调试信息
            if (!is_lcd_power_save_mode)
            {
                Serial.println("准备进入LCD低功耗模式"); // 添加调试信息
                LCD_enter_power_save_mode();
            }
        }

        if (is_ble_idle() && is_encoder_idle())
        {
            // Serial.println("检测到空闲");  // 添加调试信息
            if (!is_power_save_mode)
            {
                Serial.println("准备进入低功耗模式"); // 添加调试信息
                enter_power_save_mode();
            }
        }

        vTaskDelay(100 / portTICK_PERIOD_MS);
    }
}

void power_init()
{
    // 启动电源管理任务
    xTaskCreatePinnedToCore(
        power_management_task,
        "PowerMgmtTask",
        8192, // 与Voice_module保持一致
        NULL,
        2, // 优先级与语音模块相同
        &powerManagementTaskHandle,
        1 // APP_CPU
    );
}
